﻿using System;
using System.Collections.Generic;
using System.Data;
using viForum.Classes;
using viForum.Providers;
using visinia.SmartEngine.Cache;

namespace viForum.Controllers
{
    public class ReplyController
    {
        public static int AddReply(Reply reply)
        {
            IDataReader dr = viForumDataProvider.Provider.AddReply(reply.ThreadId, reply.UserName, reply.Date, reply.Content);
            int index = 0;
            while (dr.Read())
            {
                if (dr[0] != Convert.DBNull)
                    index = (int)dr[0];
            }
            dr.Close();
            // not expiring "vf_reply" but just "vf" to expire the whole forum cache
            DataCache.DeleteCacheMultiple("vf");
            return index;
        }

        public static void UpdateReply(Reply reply)
        {
            viForumDataProvider.Provider.UpdateReply(reply.ReplyId, reply.ThreadId, reply.UserName, reply.Date, reply.Content);
            DataCache.DeleteCacheMultiple("vf_reply");
        }

        public static void DeleteReply(int ReplyId)
        {
            viForumDataProvider.Provider.DeleteReply(ReplyId);
            // not expiring "vf_reply" but just "vf" to expire the whole forum cache
            DataCache.DeleteCacheMultiple("vf");
        }

        #region CACHE KEYS
        private const string KEY_REPLY_BY_THREAD = "vf_reply_by_thread_{0}";
        private const string KEY_LATEST_REPLY = "vf_reply_latest_{0}";
        private const string KEY_REPLIES_COUNT_BY_THREAD = "vf_reply_count_by_thread_{0}";
        private const string KEY_REPLY = "vf_reply_{0}";
        #endregion

        public static List<Reply> GetReplies(int ThreadId)
        {
            string key = string.Format(KEY_REPLY_BY_THREAD, ThreadId);
            List<Reply> replies = (List<Reply>)DataCache.GetCache(key);
            if (replies == null)
            {
                replies = FillReplies(viForumDataProvider.Provider.GetReplies(ThreadId));
                DataCache.SetCache(key, replies);
            }
            return replies;
        }

        public static Reply GetReply(int ReplyId)
        {
            string key = string.Format(KEY_REPLY, ReplyId);
            Reply reply = (Reply)DataCache.GetCache(key);
            if (reply == null)
            {
                reply = FillReply(viForumDataProvider.Provider.GetReply(ReplyId));
                DataCache.SetCache(key, reply);
            }
            return reply;
        }

        public static int GetRepliesCount(int ThreadId)
        {
            string key = string.Format(KEY_REPLIES_COUNT_BY_THREAD, ThreadId);
            if (DataCache.GetCache(key) == null)
            {
                IDataReader dr = viForumDataProvider.Provider.GetRepliesCount(ThreadId);
                int count = 0;
                while (dr.Read())
                {
                    if (dr[0] != Convert.DBNull)
                        count = (int)dr[0];
                }
                dr.Close();
                DataCache.SetCache(key, count);
            }
            return (int)DataCache.GetCache(key);
        }

        public static Reply GetLatestReply(int ThreadId)
        {
            string key = string.Format(KEY_LATEST_REPLY, ThreadId);
            Reply reply = (Reply)DataCache.GetCache(key);
            if (reply == null)
            {
                reply = FillReply(viForumDataProvider.Provider.GetLatestReply(ThreadId));
                DataCache.SetCache(key, reply);
            }
            return reply;
        }

        #region HELPERS
        private static Reply FillReply(IDataReader dr)
        {
            while (dr.Read())
            {
                return ActualRead(dr, true);
            }
            return null;
        }

        private static List<Reply> FillReplies(IDataReader dr)
        {
            List<Reply> list = new List<Reply>();
            while (dr.Read())
            {
                list.Add(ActualRead(dr, false));
            }
            dr.Close();
            return list;
        }
        private static Reply ActualRead(IDataReader dr, bool CloseDataReader)
        {
            Reply reply = new Reply();
            if (dr["ReplyId"] != Convert.DBNull)
                reply.ReplyId = (int)dr["ReplyId"];
            if (dr["ThreadId"] != Convert.DBNull)
                reply.ThreadId = (int)dr["ThreadId"];
            if (dr["UserName"] != Convert.DBNull)
                reply.UserName = (string)dr["UserName"];
            if (dr["Date"] != Convert.DBNull)
                reply.Date = (DateTime)dr["Date"];
            if (dr["ReplyContent"] != Convert.DBNull)
                reply.Content = (string)dr["ReplyContent"];
            if (CloseDataReader)
                dr.Close();
            return reply;
        }
        #endregion
    }
}
